package pe.gob.foncodes.ssa.web.controller;

import java.util.List;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import javax.faces.bean.ManagedBean;
import javax.faces.event.ActionEvent;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.log4j.Logger;
import org.primefaces.context.RequestContext;
import org.primefaces.event.NodeSelectEvent;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;
import pe.gob.foncodes.ssa.bs.administracion.controller.GenericMaintenanceController;
import pe.gob.foncodes.ssa.bs.common.util.Constante;
import pe.gob.foncodes.ssa.bs.common.util.ServiceException;
import pe.gob.foncodes.ssa.bs.seguridad.domain.Conexion;
import pe.gob.foncodes.ssa.bs.seguridad.domain.ControlAcceso;
import pe.gob.foncodes.ssa.bs.seguridad.domain.General;
import pe.gob.foncodes.ssa.bs.seguridad.domain.Modulo;
import pe.gob.foncodes.ssa.bs.seguridad.domain.Opcion;
import pe.gob.foncodes.ssa.bs.seguridad.domain.Perfil;
import pe.gob.foncodes.ssa.bs.seguridad.domain.PerfilOpcion;
import pe.gob.foncodes.ssa.bs.seguridad.domain.PerfilOpcionPK;

/**
 *
 * @author aespinoza
 */
@ManagedBean(name = "perfilController")
public class PerfilController extends GenericMaintenanceController{
    
    protected static Logger log = Logger.getLogger(PerfilController.class);
    private boolean esNuevo;
    private String txtBusquedaPerfil;
    private String mensaje;
    private TreeNode moduloTree;
    private TreeNode selectedModuloNode;
    private boolean BMuestraObs;
    private boolean BActivo;
    private boolean BEsBase;
    private List<General> lstTipoUsuario = new ArrayList<General>();
    private Map<String, String> mapaTipoUsuario = new HashMap<String, String>();
    
    private List<Perfil> lstPerfil = new ArrayList<Perfil>();
    private Perfil selectedPerfil;
        
    private Modulo selectedModuloPerfil;
    
    private List<Conexion> lstConexion = new ArrayList<Conexion>();
    private String txtBusquedaConexion;
    private Conexion selectedConexion;
    
    private Long NIdPerfilSeleccionado;
    
    Map<Long, Opcion> mapaOpciones = new HashMap<Long, Opcion>();
    
    private List<Opcion> listaOpcionesAutorizadas = new ArrayList<Opcion>();

    private TreeNode moduloTreePerfil;
    private TreeNode selectedModuloNodePerfil;
    
    private TreeNode visualizaTree;
    
    @Override
    public void init() {
        mensaje = "";
        setBean(new Perfil());
        selectedPerfil = null;
        selectedModuloPerfil = null;
        esNuevo = false;
        BMuestraObs = false;
        BEsBase = false;
        loadInicialTree();
        try {
            lstTipoUsuario = getService().findByNamedQuery("General.findByTxtDominio", new Object[]{Constante.DOMINIO_TIPO_USUARIO});
            mapaTipoUsuario = new HashMap<String, String>();
            for (General general : lstTipoUsuario) {
                mapaTipoUsuario.put(general.getTxtValor(), general.getTxtParametro());
            }
        } catch (Exception e) {
        }
    }
    
    @Override
    public void search(ActionEvent event) throws Exception{
        selectedPerfil = null;
        if(selectedModuloNode == null){
            setMessageError(new Exception("Debe seleccionar un modulo"));
            return;
        }
        if(this.txtBusquedaPerfil == null){
            this.txtBusquedaPerfil = "";
        }
        if(txtBusquedaPerfil.trim().equals("")){
            setMessageError(new Exception("Debe ingresar el perfil a buscar"));
            lstPerfil = new ArrayList<Perfil>();
            return;
        }else{
            lstPerfil = getService().findByNamedQuery("Perfil.findByTxtPerfilAndNidModulo", new Object[]{"%" + txtBusquedaPerfil.trim().toUpperCase() + "%", selectedModuloPerfil.getId()});
        }
        setBeanList(lstPerfil);
    }
    
    public void listar() throws ServiceException{
        if(selectedModuloPerfil != null){
            lstPerfil = getService().findByNamedQuery("Perfil.findByNidModulo", new Object[]{selectedModuloPerfil.getId()});
            setBeanList(lstPerfil);
        }
    }
    
    public void loadInicialTree(){
        moduloTree = new DefaultTreeNode("root", null);
        try {
            List<Modulo> lstModuloInicial = getService().findByNamedQuery("Modulo.findOnlyNidModuloPadreAndFlgActivo", new Object[]{Constante.ESTADO_ACTIVO});
            for (Modulo modulo : lstModuloInicial) {
                TreeNode padre = new DefaultTreeNode(modulo, moduloTree);
            }
        } catch (ServiceException ex) {
            log.error("ERROR EN loadInicialTree: "+ex);
        }
    }
    
    public void onNodeSelect(NodeSelectEvent event) {
        if(event.getTreeNode() != null){
            TreeNode node = event.getTreeNode();
            node.setExpanded(true);
            List<Modulo> lstModuloHijos = new ArrayList<Modulo>();
            try {
                node.getChildren().clear();
                selectedModuloPerfil = (Modulo) node.getData();
                lstModuloHijos = getService().findByNamedQuery("Modulo.findByNidModuloPadreAndFlgActivo", new Object[]{((Modulo) node.getData()).getId(), Constante.ESTADO_ACTIVO});
                for (Modulo modulo : lstModuloHijos) {
                    TreeNode hijo = new DefaultTreeNode(modulo, node);
                }
                lstPerfil = getService().findByNamedQuery("Perfil.findByNidModulo", new Object[]{selectedModuloPerfil.getId()});
                setBeanList(lstPerfil);
            } catch (ServiceException ex) {
                log.error("ERROR EN onNodeSelect: " + ex);
            }
        }
    }
    
    public void loadOpcionesPadreTree(TreeNode hijo, Modulo moHijo) throws ServiceException {
        //Se cargan las opciones del modulo
        List<Opcion> lstOpcionPadre = getService().findByNamedQuery("Opcion.findOnlyNidOpcionPadreAndFlgActivo", new Object[]{moHijo.getId(), Constante.ESTADO_ACTIVO});
        for (Opcion opPadre : lstOpcionPadre) {
            TreeNode opcionPadre = new DefaultTreeNode("document",opPadre, hijo);
            opcionPadre.setExpanded(true);
            loadOpcionesHijoTree(opcionPadre, opPadre, moHijo);
        }
        
        List<Modulo> lstModuloHijos = getService().findByNamedQuery("Modulo.findByNidModuloPadreAndFlgActivo", new Object[]{moHijo.getId(), Constante.ESTADO_ACTIVO});
        for (Modulo modulo : lstModuloHijos) {
            TreeNode hijoMo = new DefaultTreeNode(modulo, hijo);
            hijoMo.setExpanded(true);
            loadOpcionesPadreTree(hijoMo, modulo);
        }
    }
    
    public void loadOpcionesHijoTree(TreeNode hijo, Opcion opHijo, Modulo moPadre) throws ServiceException {
        List<Opcion> lstOpcionHijos = getService().findByNamedQuery("Opcion.findByNidOpcionPadreAndFlgActivo", new Object[]{opHijo.getId(), moPadre.getId(), Constante.ESTADO_ACTIVO});
        for (Opcion opcion : lstOpcionHijos) {
            TreeNode nieto = new DefaultTreeNode("document",opcion, hijo);
            nieto.setExpanded(true);
            loadOpcionesHijoTree(nieto, opcion, moPadre);
        }
    }
    
    public void muestraObservacion() {
        BMuestraObs = (BActivo)?false:true;
    }
    
    public void nuevo() {
        RequestContext context = RequestContext.getCurrentInstance();
        if(selectedModuloNode == null){
            setMessageError(new Exception("Debe seleccionar un modulo"));
            esNuevo = false;
        } else {
            BActivo = true;
            esNuevo = true;
            BEsBase = false;
            BMuestraObs = false;
            selectedConexion = null;
            selectedModuloPerfil = (Modulo) selectedModuloNode.getData();
            Perfil perfil = new Perfil();
            perfil.setNidModulo(selectedModuloPerfil);
            if(selectedModuloPerfil.getId().equals(Constante.NID_MODULO_SSA)){
                perfil.setTipUsuario(Constante.USUARIO_TIPO_INTERNO);
            }
            setBean(perfil);
            context.execute("wDetalleModuloPerfil.show()");
        }
    }
    
    public void loadOpciones(ActionEvent event) throws Exception {
        RequestContext context = RequestContext.getCurrentInstance();
        if(selectedPerfil == null){
            setMessageError(new Exception("Debe seleccionar un perfil"));
            return;
        }else{
            if(selectedPerfil.getFlgActivo().equals(Constante.ESTADO_INACTIVO)){
                setMessageError(new Exception("El perfil se encuentra desactivado"));
                return;
            }else{
                if(selectedPerfil.getFlgBase().equals(Constante.FLAG_PERFIL_BASE)){
                    setMessageError(new Exception("No se debe configurar opciones a este perfil base"));
                    return;
                }else{
                    listaOpcionesAutorizadas = new ArrayList<Opcion>();
                    mapaOpciones = new HashMap<Long, Opcion>();
                    NIdPerfilSeleccionado = selectedPerfil.getId();
                    //Verificar el padre
                    moduloTreePerfil = new DefaultTreeNode("root", null);
                    selectedModuloNodePerfil = new DefaultTreeNode(selectedModuloNode.getData(), moduloTreePerfil);
                    listarOpcionesDePerfil(selectedModuloNodePerfil);
                }
            }
            context.execute("wGestionarOpcionesPerfil.show()");
        }
    }
    
    @Override
    public void load(ActionEvent event) throws Exception {
        RequestContext context = RequestContext.getCurrentInstance();
        if(selectedModuloNode == null){
            setMessageError(new Exception("Debe seleccionar un modulo"));
            return;
        }
        if(selectedPerfil == null){
            setMessageError(new Exception("Debe seleccionar un perfil"));
            esNuevo = false;
        }else {
            esNuevo = false;
            Perfil perfil = (Perfil) getService().findById(Perfil.class, selectedPerfil.getId());
            selectedConexion = perfil.getNidConexion();
            setBean(perfil);
            if(perfil.getFlgActivo().equals(Constante.ESTADO_ACTIVO)){
                BActivo = true;
            }else{
                BActivo = false;
            }
            if(BActivo){
                BMuestraObs = false;
            }else{
                BMuestraObs = true;
            }
            if(perfil.getFlgBase().equals(Constante.FLAG_PERFIL_BASE)){
                BEsBase = true;
            }else{
                BEsBase = false;
            }
            context.execute("wDetalleModuloPerfil.show()");
        }
    }
    
    @Override
    public void clean(ActionEvent event) throws Exception {
        setBean(new Perfil());
    }
    
    public void limpiarBusquedaConexion(){
        this.txtBusquedaConexion="";
        lstConexion = new ArrayList<Conexion>();
    }
            
    public void searchConexion() throws Exception {
        if (this.txtBusquedaConexion ==null){
           this.txtBusquedaConexion="";
        }
        if(this.txtBusquedaConexion.equals("")){
            setMessageError(new Exception("Debe ingresar la conexion"));
            return;
        }
        lstConexion = getService().findByNamedQuery("Conexion.findByTxtConexion", new Object[]{"%" + txtBusquedaConexion + "%"});
        selectedConexion =null;
    }
    
    public void actualizarSeleccionConexion(Conexion conexionSeleccionado){
        if(conexionSeleccionado != null){
            selectedConexion = conexionSeleccionado;
            Perfil perfil = (Perfil)getBean();
            perfil.setNidConexion(selectedConexion);
        }
    }
            
    @Override
    public boolean validate() throws Exception {
        boolean success = true;
        Perfil perfil = (Perfil)getBean();
        if(perfil.getNidConexion() == null){
            setMessageError(new Exception("Se debe ingresar la conexion."));
            success = false;
            return success;
        }
        if (perfil.getTxtPerfil() == null ){
            perfil.setTxtPerfil("");
        }
        if(perfil.getTxtPerfil().trim().equals("")) {
            setMessageError(new Exception("Se debe ingresar el nombre."));
            success = false;
            return success;
        }
        /*if (!perfil.getTxtPerfil().equals("")) {
            List listaPerfil = getService().findByObjectDif("Perfil", "txtPerfil", perfil.getTxtPerfil().trim(), perfil.getId());
            if (listaPerfil != null && listaPerfil.size() != 0) {
                setMessageError(new Exception("Ya existe un perfil registrado con el mismo nombre."));
                success = false;
                return success;
            }
        }*/
        if(perfil.getTipUsuario() == null){
            setMessageError(new Exception("Se debe seleccionar el Tipo de Usuario."));
            success = false;
            return success;
        }
        if(perfil.getTipUsuario().equals(Constante.NO_OPTION_SELECTED)){
            setMessageError(new Exception("Se debe seleccionar el Tipo de Usuario."));
            success = false;
            return success;
        }
        if(perfil.getFlgActivo().equals(Constante.ESTADO_INACTIVO)) {
            if (perfil.getTxtObservacion() == null ){
                perfil.setTxtObservacion("");
            }
            if(perfil.getTxtObservacion().equals("")){
                setMessageError(new Exception("Se debe ingresar la observación."));
                success = false;
                return success;
            }
        }
        if(perfil.getFlgActivo().equals(Constante.ESTADO_ACTIVO) && !esNuevo) {
            perfil.setTxtObservacion(null);
        }
        return success;
    }
    
    public void savePerfil(ActionEvent event) throws Exception {
        RequestContext context = RequestContext.getCurrentInstance();
        Perfil perfil = (Perfil)getBean();
        ControlAcceso control = ((ControlAcceso) getSpringBean(Constante.SESSION_ACCESO));
        perfil.setFlgActivo((BActivo)?Constante.ESTADO_ACTIVO:Constante.ESTADO_INACTIVO);
        perfil.setFlgBase((BEsBase)?Constante.FLAG_PERFIL_BASE:Constante.ESTADO_INACTIVO);
        perfil.setNIdCtrlAccesoWeb(control.getId());
        setBean(perfil);
        try {
            //Nuevo
            if(esNuevo){
                if (validate()) {
                    super.beforeSave(event);
                    super.doSaveSinProp(event);
                    afterSave(event);
                    context.execute("wDetalleModuloPerfil.hide()");
                }
            //Modificar
            }else{
                if (validate()) {
                    super.beforeUpdate(event);
                    super.doUpdate(event);
                    afterUpdate(event);
                    context.execute("wDetalleModuloPerfil.hide()");
                }
            }
        } catch (Exception e) {
            log.error(e);
        }
    }
    
    public void copiaPropiedades(){
        try {
            BeanUtils.copyProperties(getBeanAuditoria(), getBean());
        } catch (Exception e) {
            log.error(e);
        }
    }
    
    @Override
    public void afterSave(ActionEvent event) throws Exception {
        esNuevo = false;
        setMessageSuccess("Se creo el perfil " + "'" + ((Perfil) getBean()).getTxtPerfil() + "'" + " satisfactoriamente.");
        log.info("End of Transaction: 'Save'");
    }
    
    @Override
    public void afterUpdate(ActionEvent event) throws Exception {
        setMessageSuccess("Se actualizó el perfil " + "'" + ((Perfil) getBean()).getTxtPerfil() + "'" + " satisfactoriamente.");
        log.info("End of Transaction: 'Update'");
    }
    
    public void onNodeSelectActivos(NodeSelectEvent event) {
        if(event.getTreeNode() != null){
            TreeNode node = event.getTreeNode();
            listarOpcionesDePerfil(node);
        }
    }
    
    public PerfilOpcion existeOpcionEnPerfil(List<PerfilOpcion> lista, Opcion opcion){
        PerfilOpcion po=null;
        for (PerfilOpcion op : lista) {
            if(op.getOpcion().getId().equals(opcion.getId())){
                po=op;
                break;
            }
        }
        return po;
    }
    
    public void listarOpcionesDePerfil(TreeNode node) {
        if (node != null) {
            listaOpcionesAutorizadas = new ArrayList<Opcion>();
            node.setExpanded(true);
            try {
                if (node.getData() instanceof Modulo) {
                    node.getChildren().clear();
                    selectedModuloPerfil = (Modulo) node.getData();
                    loadOpcionesPadreTree(node, selectedModuloPerfil);
                }
            } catch (ServiceException ex) {
                log.error("ERROR EN onNodeSelectActivos: " + ex);
            }
            if (node.getChildCount() >= 0) {
                List<TreeNode> hijosNodo = node.getChildren();
                if (!hijosNodo.isEmpty()) {
                    List<Object[]> lstObject = new ArrayList<Object[]>();
                    List<PerfilOpcion> lstOpcionPadre = new ArrayList<PerfilOpcion>();
                    Modulo moduloSelected = null;
                    Opcion opcionPadreSelected = null;
                    if (node.getData() instanceof Modulo) {
                        if (hijosNodo.get(0).getData() instanceof Opcion) {
                            moduloSelected = (Modulo) node.getData();
                            try {
                                lstObject = getService().findByNamedQuery("PerfilOpcion.findOnlyPerfilOpcionPadreByNidPerfil", new Object[]{moduloSelected.getId(), Constante.ESTADO_ACTIVO, NIdPerfilSeleccionado});
                                if (!lstObject.isEmpty()) {
                                    for (Object[] obj : lstObject) {
                                        lstOpcionPadre.add((PerfilOpcion) obj[0]);
                                    }
                                }
                            } catch (Exception e) {
                                log.error("ERROR EN onNodeSelectActivos = " + e.getMessage());
                            }
                        }
                    } else {
                        //si es opcion
                        opcionPadreSelected = (Opcion) node.getData();
                        moduloSelected = opcionPadreSelected.getNidModulo();
                        try {
                            lstObject = getService().findByNamedQuery("PerfilOpcion.findPerfilOpcionByNidPerfil", new Object[]{moduloSelected.getId(), Constante.ESTADO_ACTIVO, NIdPerfilSeleccionado, opcionPadreSelected.getId()});
                            if(!lstObject.isEmpty()){
                                for (Object[] obj : lstObject) {
                                    lstOpcionPadre.add((PerfilOpcion)obj[0]);
                                }
                            }
                        } catch (Exception e) {
                            log.error("ERROR EN onNodeSelectActivos = " + e.getMessage());
                        }
                    }
                    Opcion op = null;
                    Opcion opTmp = null;
                    PerfilOpcion po = null;
                    for (TreeNode nodoOpcion : node.getChildren()) {
                        if (nodoOpcion.getData() instanceof Opcion) {
                            op = new Opcion();
                            opTmp = (Opcion) nodoOpcion.getData();
                            op.setId(opTmp.getId());
                            op.setTxtOpcion(opTmp.getTxtOpcion());
                            op.setNidModulo(opTmp.getNidModulo());
                            op.setNidOpcionPadre(opTmp.getNidOpcionPadre());
                            po = existeOpcionEnPerfil(lstOpcionPadre, op);
                            if (po != null) {
                                op.setFlgActivo(Constante.ESTADO_ACTIVO);
                                op.setBflgActivo(true);
                                op.setBflgConsulta((po.getFlgConsulta().equals(Constante.ESTADO_ACTIVO) ? true : false));
                            } else {
                                op.setFlgActivo(Constante.ESTADO_INACTIVO);
                                op.setBflgActivo(false);
                                op.setBflgConsulta(false);
                            }
                            listaOpcionesAutorizadas.add(op);
                        }
                    }
                }
            }
        }
    }
    
    public void agregaOpcionParaPerfil(Opcion opcion){
        if(!opcion.isBflgActivo()){
            opcion.setBflgConsulta(false);
        }else{
            opcion.setBflgConsulta(true);
        }
        mapaOpciones.put(opcion.getId(), opcion);
    }
    
    public void validaPerfilOpcionEnCascada() throws Exception{
        RequestContext context = RequestContext.getCurrentInstance();
        Perfil perfil = (Perfil) getService().findById(Perfil.class, NIdPerfilSeleccionado);
        boolean bExisteEnUsuario = getService().validaExistenciaEnPerfilOAutorizacion(perfil.getId(), null, "3");
        if(bExisteEnUsuario){
            context.execute("abreConfirmacionPerfil()");
        }else{
            asignaOpcionesAlPerfil(bExisteEnUsuario, false);
        }
    }
    
    public void asignaOpcionesAlPerfil(boolean bExisteEnUsuario, boolean bAplicaCascada) throws Exception{        
        Object bean = getBean();
        PerfilOpcion perOpcion = null;
        PerfilOpcion perfilOpcion = null;
        Perfil perfil = (Perfil) getService().findById(Perfil.class, NIdPerfilSeleccionado);
        List<Opcion> listaOpcionesParaAgregar = null;
        ControlAcceso control = ((ControlAcceso) getSpringBean(Constante.SESSION_ACCESO));
        for (Opcion opcion : listaOpcionesAutorizadas) {
            if(mapaOpciones.containsKey(opcion.getId())){
                opcion = mapaOpciones.get(opcion.getId());
            }
            if(bExisteEnUsuario){
                listaOpcionesParaAgregar = new ArrayList<Opcion>();
                listaOpcionesParaAgregar.add(opcion);
            }else{
                if(bAplicaCascada){
                    listaOpcionesParaAgregar = new ArrayList<Opcion>();
                    listaOpcionesParaAgregar.add(opcion);
                }else{
                    listaOpcionesParaAgregar = getService().findByNamedQuery("Opcion.findByNidOpcionAndNidOpcionPadreAndFlgActivo", new Object[]{opcion.getNidModulo().getId(), opcion.getId(), Constante.ESTADO_ACTIVO});
                }
            }
            if (opcion.isBflgActivo()) {
                for (Opcion opAgrega : listaOpcionesParaAgregar) {
                    perOpcion = (PerfilOpcion) getService().findByNamedQueryUniqueRow("PerfilOpcion.findByNidPerfilAndNidOpcion", new Object[]{NIdPerfilSeleccionado, opAgrega.getId()});
                    if (perOpcion == null) {
                        //nuevo
                        perfilOpcion = new PerfilOpcion();
                        perfilOpcion.setPerfil(perfil);
                        perfilOpcion.setOpcion((Opcion)getService().findById(Opcion.class,opAgrega.getId()));
                        perfilOpcion.setFlgConsulta(opcion.isBflgConsulta() ? Constante.FLAG_CONSULTA : Constante.ESTADO_INACTIVO);
                        perfilOpcion.setPerfilOpcionPK(new PerfilOpcionPK(perfil.getId(), opAgrega.getId()));
                        perfilOpcion.setNIdCtrlAccesoWeb(control.getId());
                        setBean(perfilOpcion);
                        super.beforeSave(null);
                        super.doSaveSinPropSinID(null);
                        if(bAplicaCascada){
                            //agrega autorizaciones 
                            try {
                                getService().actualizaPerfilOpcionEnCascada(perfil.getId(), opAgrega.getId() ,perfilOpcion.getFlgConsulta(), Constante.ESTADO_ACTIVO, control.getId(), "SP_AGREGA_PEROPCENUSUPERFIL");
                            } catch (Exception e) {
                                log.error("ERROR EN asignaOpcionesAlPerfil: "+e.getMessage());
                            }
                        }
                    } else {
                        //actualizar
                        try {
                            perOpcion.setNIdCtrlAccesoWeb(control.getId());
                            perOpcion.setFlgConsulta(opcion.isBflgConsulta() ? Constante.ESTADO_ACTIVO : Constante.ESTADO_INACTIVO);
                            getService().executeUpdate("PerfilOpcion.updateFlgActivo", new Object[]{perOpcion.getFlgConsulta(), perOpcion.getNIdCtrlAccesoWeb(), perOpcion.getPerfilOpcionPK().getNidOpcion(), perOpcion.getPerfilOpcionPK().getNidPerfil()});
                        } catch (Exception e) {
                            log.error("ERROR en quitar autorizaciones =" + e);
                        }
                        if(bAplicaCascada){
                            //actualizar flgConsulta de autorizaciones
                            getService().actualizaPerfilOpcionEnCascada(perfil.getId(), opAgrega.getId() ,perOpcion.getFlgConsulta(), Constante.ESTADO_ACTIVO, control.getId(), "SP_ACTUALIZA_PEROPCENUSUPERFIL");
                        }
                    }
                }
            } else {
                //eliminar
                for (Opcion opAgrega : listaOpcionesParaAgregar) {
                    perOpcion = (PerfilOpcion) getService().findByNamedQueryUniqueRow("PerfilOpcion.findByNidPerfilAndNidOpcion", new Object[]{NIdPerfilSeleccionado, opAgrega.getId()});
                    if(perOpcion != null){      
                        perOpcion.setOpcion(null);
                        perOpcion.setPerfil(null);
                        setBean(perOpcion);
                        super.beforeDeleteSinID(null);
                        super.doDeleteSinProp(null);
                        if(bAplicaCascada){
                            //desactivar autorizaciones
                            getService().actualizaPerfilOpcionEnCascada(perfil.getId(), opAgrega.getId() ,perOpcion.getFlgConsulta(), Constante.ESTADO_INACTIVO, control.getId(), "SP_ELIMINA_PEROPCENUSUPERFIL");
                        }
                    }
                }
            }
        }
        setBean(bean);
        if(bAplicaCascada){
            setMessageSuccess("Se configuraron las opciones del perfil en cascada satisfactoriamente.");
        }else{
            setMessageSuccess("Se configuraron las opciones satisfactoriamente");
        }
    }
    
    public boolean isBActivo() {
        return BActivo;
    }

    public void setBActivo(boolean BActivo) {
        this.BActivo = BActivo;
    }

    public boolean isBMuestraObs() {
        return BMuestraObs;
    }

    public void setBMuestraObs(boolean BMuestraObs) {
        this.BMuestraObs = BMuestraObs;
    }

    public boolean isEsNuevo() {
        return esNuevo;
    }

    public void setEsNuevo(boolean esNuevo) {
        this.esNuevo = esNuevo;
    }

    public List<Perfil> getLstPerfil() {
        return lstPerfil;
    }

    public void setLstPerfil(List<Perfil> lstPerfil) {
        this.lstPerfil = lstPerfil;
    }

    public String getMensaje() {
        return mensaje;
    }

    public void setMensaje(String mensaje) {
        this.mensaje = mensaje;
    }

    public TreeNode getModuloTree() {
        return moduloTree;
    }

    public void setModuloTree(TreeNode moduloTree) {
        this.moduloTree = moduloTree;
    }

    public TreeNode getSelectedModuloNode() {
        return selectedModuloNode;
    }

    public void setSelectedModuloNode(TreeNode selectedModuloNode) {
        this.selectedModuloNode = selectedModuloNode;
    }

    public Modulo getSelectedModuloPerfil() {
        return selectedModuloPerfil;
    }

    public void setSelectedModuloPerfil(Modulo selectedModuloPerfil) {
        this.selectedModuloPerfil = selectedModuloPerfil;
    }

    public Perfil getSelectedPerfil() {
        return selectedPerfil;
    }

    public void setSelectedPerfil(Perfil selectedPerfil) {
        this.selectedPerfil = selectedPerfil;
    }

    public String getTxtBusquedaPerfil() {
        return txtBusquedaPerfil;
    }

    public void setTxtBusquedaPerfil(String txtBusquedaPerfil) {
        this.txtBusquedaPerfil = txtBusquedaPerfil;
    }

    public List<General> getLstTipoUsuario() {
        return lstTipoUsuario;
    }

    public void setLstTipoUsuario(List<General> lstTipoUsuario) {
        this.lstTipoUsuario = lstTipoUsuario;
    }

    public Map<String, String> getMapaTipoUsuario() {
        return mapaTipoUsuario;
    }

    public void setMapaTipoUsuario(Map<String, String> mapaTipoUsuario) {
        this.mapaTipoUsuario = mapaTipoUsuario;
    }

    public List<Conexion> getLstConexion() {
        return lstConexion;
    }

    public void setLstConexion(List<Conexion> lstConexion) {
        this.lstConexion = lstConexion;
    }

    public Conexion getSelectedConexion() {
        return selectedConexion;
    }

    public void setSelectedConexion(Conexion selectedConexion) {
        this.selectedConexion = selectedConexion;
    }

    public String getTxtBusquedaConexion() {
        return txtBusquedaConexion;
    }

    public void setTxtBusquedaConexion(String txtBusquedaConexion) {
        this.txtBusquedaConexion = txtBusquedaConexion;
    }

    public Long getNIdPerfilSeleccionado() {
        return NIdPerfilSeleccionado;
    }

    public void setNIdPerfilSeleccionado(Long NIdPerfilSeleccionado) {
        this.NIdPerfilSeleccionado = NIdPerfilSeleccionado;
    }

    public Map<Long, Opcion> getMapaOpciones() {
        return mapaOpciones;
    }

    public void setMapaOpciones(Map<Long, Opcion> mapaOpciones) {
        this.mapaOpciones = mapaOpciones;
    }

    public boolean isBEsBase() {
        return BEsBase;
    }

    public void setBEsBase(boolean BEsBase) {
        this.BEsBase = BEsBase;
    }

    public List<Opcion> getListaOpcionesAutorizadas() {
        return listaOpcionesAutorizadas;
    }

    public void setListaOpcionesAutorizadas(List<Opcion> listaOpcionesAutorizadas) {
        this.listaOpcionesAutorizadas = listaOpcionesAutorizadas;
    }

    public TreeNode getModuloTreePerfil() {
        return moduloTreePerfil;
    }

    public void setModuloTreePerfil(TreeNode moduloTreePerfil) {
        this.moduloTreePerfil = moduloTreePerfil;
    }

    public TreeNode getSelectedModuloNodePerfil() {
        return selectedModuloNodePerfil;
    }

    public void setSelectedModuloNodePerfil(TreeNode selectedModuloNodePerfil) {
        this.selectedModuloNodePerfil = selectedModuloNodePerfil;
    }
    
    public TreeNode getVisualizaTree() {
        return visualizaTree;
    }

    public void setVisualizaTree(TreeNode visualizaTree) {
        this.visualizaTree = visualizaTree;
    }
    
    public void visualizaOpciones() throws ServiceException{
        visualizaTree = new DefaultTreeNode("root", null);
        NIdPerfilSeleccionado = selectedPerfil.getId();
        Modulo moduloPadre = (Modulo) selectedModuloNode.getData();
        TreeNode treePadre = new DefaultTreeNode(moduloPadre, visualizaTree);
        treePadre.setExpanded(true);
        loadPadreTreeVisualiza(moduloPadre, treePadre);
    }
    
    public void loadPadreTreeVisualiza(Modulo moduloPadre, TreeNode treePadre) throws ServiceException {
        List<Object[]> lstObject = getService().findByNamedQuery("PerfilOpcion.findOnlyPerfilOpcionPadreByNidPerfil", new Object[]{moduloPadre.getId(), Constante.ESTADO_ACTIVO, NIdPerfilSeleccionado});
        List<PerfilOpcion> lstOpcionPadre = new ArrayList<PerfilOpcion>();
        for (Object[] obj : lstObject) {
            lstOpcionPadre.add((PerfilOpcion)obj[0]);
        }
        for (PerfilOpcion perfilOpcion : lstOpcionPadre) {
            TreeNode padre = new DefaultTreeNode("document", perfilOpcion, treePadre);
            padre.setExpanded(true);
            loadHijoTreeVisualiza(moduloPadre, padre, perfilOpcion, NIdPerfilSeleccionado);
        }
        List<Modulo> lstModuloHijos = getService().findByNamedQuery("Modulo.findByNidModuloPadreAndFlgActivo", new Object[]{moduloPadre.getId(), Constante.ESTADO_ACTIVO});
        for (Modulo modulo : lstModuloHijos) {
            TreeNode hijoMo = new DefaultTreeNode(modulo, treePadre);
            hijoMo.setExpanded(true);
            loadPadreTreeVisualiza(modulo, hijoMo);
        }
    }
    
    public void loadHijoTreeVisualiza(Modulo moduloSelected, TreeNode hijo, PerfilOpcion opHijo, Long NIdPerfil) throws ServiceException {
        List<Object[]> lstObject = getService().findByNamedQuery("PerfilOpcion.findPerfilOpcionByNidPerfil", new Object[]{moduloSelected.getId(), Constante.ESTADO_ACTIVO, NIdPerfilSeleccionado, opHijo.getOpcion().getId()});
        List<PerfilOpcion> lstOpcionHijos = new ArrayList<PerfilOpcion>();
        for (Object[] obj : lstObject) {
            lstOpcionHijos.add((PerfilOpcion)obj[0]);
        }
        for (PerfilOpcion perfilOpcion : lstOpcionHijos) {
            TreeNode nieto = new DefaultTreeNode("document", perfilOpcion, hijo);
            nieto.setExpanded(true);
            loadHijoTreeVisualiza(moduloSelected, nieto, perfilOpcion, NIdPerfil);
        }
    }
}